//Include("Mz.Class");

/**
 * 自定义的事件对象
 * @author meizz
 * @name Mz.Event
 * @config {String} type 事件的名称
 * @config {Boolean} returnValue 当事件发生之后处理结果的返回值
 * @config {Mz.Class} target 在事件被触发后传递的对象
 * @config {Mz.Class} currentTarget 触发该事件的对象
 */
Mz.Event = function(type, target){
    this.type = type;
    this.returnValue = true;
    this.target = target || null;
    this.currentTarget = null;
};

/**
 * 扩展Mz.Class来添加自定义事件
 * @param {String} type 自定义事件的名称
 * @param {Function} handler 自定义事件被触发时应该调用的回调函数
 * @param {String} key 可选参数，绑定到事件上的函数对应的索引key
 */
Mz.Class.prototype.addEventListener = function(type, handler, key){
    if (typeof handler != "function") {
        throw("addEventListener:" + handler + " is not a function");
    }
    if (!this.__listeners) {
        this.__listeners = {};
    }
    var t = this.__listeners, id;
    if (typeof key == "string" && key) {
        if (/[^\w\-]/.test(key)) {
            throw("nostandard key:" + key);
        } else {
            handler._hashCode = key;
            id = key;
        }
    }
    if (type.indexOf("on") != 0){
        type = "on"+ type;
    }
    if (typeof t[type] != "object") {
        t[type] = {};
    }
    id = id || Mz.Class.guid();
    handler._hashCode = id;
    //if (t[type][id]) {
    //    throw("repeat key:" + id);
    //}
    t[type][id] = handler;
};
 
/**
 * 删除自定义事件中绑定的一个回调函数。如果第二个参数handler没有被
 * 绑定到对应的自定义事件中，什么也不做。
 * @param {String} type 自定义事件的名称
 * @param {Function} handler 需要删除的自定义事件的函数或者该函数对应的索引key
 */
Mz.Class.prototype.removeEventListener = function(type, handler){
    if (typeof handler == "function") {
        handler = handler._hashCode;
    } else if (typeof handler != "string") {
        return;
    }
    if (!this.__listeners) {
        this.__listeners = {};
    }
    if (type.indexOf("on") != 0){
        type = "on"+ type;
    }
    var t = this.__listeners;
    if (!t[type]) {
        return;
    }
    if (t[type][handler]) {
        delete t[type][handler];
    }
};


/**
 * 派发自定义事件，使得绑定到自定义事件上面的函数都会被执行。
 * 但是这些绑定函数的执行顺序无法保证。
 * 处理会调用通过addEventListenr绑定的自定义事件回调函数之外，还会调用
 * 直接绑定到对象上面的自定义事件。例如：
 * myobj.onMyEvent = function(){}
 * myobj.addEventListener("onMyEvent", function(){});
 * @param {Mz.Event} event 派发的自定义事件类型
 */
Mz.Class.prototype.dispatchEvent = function(event){
    if (!this.__listeners) {
        this.__listeners = {};
    }
    var i, t = this.__listeners, p = event.type;
    event.target = event.target || this;
    event.currentTarget = this;
    if (typeof this[p] == "function") {
        this[p](event);
    }
    if (p.indexOf("on") != 0) {
        p = "on" + p;
    }
    if (typeof t[p] == "object") {
        for (i in t[p]) {
            if (typeof t[p][i] == "function") {
                t[p][i].call(this, event);
            }
        }
    }
    return event.returnValue;
};
